﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Ribbon.cs" company="Geologische Bundesanstalt">
//   Thomas Heuberger, 2014-02
// </copyright>
// <summary>
//   Defines the Ribbon type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace AttachmentHandler {
    using System;
    using System.Collections.Generic;
    using System.Deployment.Application;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Windows;

    using Office = Microsoft.Office.Core;
    using Outlook = Microsoft.Office.Interop.Outlook;

    /// <summary>
    /// The ribbon.
    /// </summary>
    [ComVisible(true)]
    public class Ribbon : Office.IRibbonExtensibility {
        /// <summary>
        /// The on configure button click handler.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        public void OnConfigureButtonClick(Office.IRibbonControl control) {
            var settingsWindow = new SettingsWindow();
            settingsWindow.ShowDialog();
        }

        /// <summary>
        /// The on save attachments button click handler.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        public void OnSaveAttachmentsButtonClick(Office.IRibbonControl control) {
            if (!DoPreflightCheck())
                return;

            var mailItems = new List<Outlook.MailItem>();

            if (control.Context is Outlook.Folder) {
                var clickedFolder = control.Context as Outlook.Folder;

                // get every item from the folder
                mailItems = clickedFolder.Items.OfType<Outlook.MailItem>().Where(i => (!Globals.ThisAddIn.Settings.OnlyUnread || i.UnRead) && i.Attachments.Count > 0).ToList();
            }

            if (control.Context is Outlook.Selection) {
                var selection = control.Context as Outlook.Selection;

                // get only selected mail items
                mailItems = selection.OfType<Outlook.MailItem>().Where(i => (!Globals.ThisAddIn.Settings.OnlyUnread || i.UnRead) && i.Attachments.Count > 0).ToList();
            }

            if (mailItems.Count > 0) {
                var progressWindow = new ProgressWindow(mailItems);
                progressWindow.ShowDialog();
            }
            else {
                // actually this should never be called as the button should be disabled anyways ...
                MessageBox.Show("There is nothing to do!", "Attachment Handler", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// The on run button click event handler.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        public void OnRunButtonClick(Office.IRibbonControl control) {
            try {
                if (!DoPreflightCheck())
                    return;

                // get the outlook folder from the settings. cannot be null because of the ValidateSettings check from above 
                var outlookFolder = Globals.ThisAddIn.Settings.SourceFolder;

                // get every item from the folder
                // ReSharper disable once PossibleNullReferenceException
                var mailItems = outlookFolder.Items.OfType<Outlook.MailItem>().Where(i => (!Globals.ThisAddIn.Settings.OnlyUnread || i.UnRead) && i.Attachments.Count > 0).ToList();

                if (mailItems.Count > 0) {
                    var progressWindow = new ProgressWindow(mailItems);
                    progressWindow.ShowDialog();
                }
                else {
                    // actually this should never be called as the button should be disabled anyways ...
                    MessageBox.Show("There is nothing to do!", "Attachment Handler", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            } catch (Exception exception) {
                var message = "There was an error accessing your Outlook source folder!" + Environment.NewLine + "Check your settings! " + "The error was: " + "\"" + exception.Message + "\"";
                MessageBox.Show(message, "Attachment Handler", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// The get label method for the context menu.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetLabelContextMenu(Office.IRibbonControl control) {
            var clickedFolder = control.Context as Outlook.Folder;
            if (clickedFolder == null) return string.Empty;

            var label = clickedFolder.FolderPath.Split('\\').Last();
            return string.Format("Save attachments from {1}mails from folder \"{0}\"", label, Globals.ThisAddIn.Settings.OnlyUnread ? "unread " : string.Empty);
        }

        /// <summary>
        /// The get build label version.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetLabelBuildVersion(Office.IRibbonControl control) {
            try {
                return "Build " + ApplicationDeployment.CurrentDeployment.CurrentVersion;
            } catch (Exception) {
                return "Error getting Build Number!";
            }
        }

        /// <summary>
        /// The get label method for selected mail items.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetLabelMailItems(Office.IRibbonControl control) {
            var selection = control.Context as Outlook.Selection;
            if (selection == null) return string.Empty;

            var attachments = new List<Outlook.Attachment>();
            var mailItems = selection.OfType<Outlook.MailItem>().Where(i => (!Globals.ThisAddIn.Settings.OnlyUnread || i.UnRead)).ToList();

            foreach (var mailItem in mailItems) {
                attachments.AddRange(Utilities.GetMailAttachments(mailItem));
            }

            if (mailItems.Count > 1)
                return string.Format("Save all attachments ({0}) from {1} mails", attachments.Count, mailItems.Count);
            if (mailItems.Count == 1)
                return string.Format(
                    "Save all attachments ({0}) from mail \"{1}\"",
                    Utilities.GetMailAttachments(mailItems[0]).Count,
                    mailItems[0].Subject);
            return "No attachments to save!";
        }

        /// <summary>
        /// The get enabled method for selected mail items.
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool GetMailItemsContextMenuEnabled(Office.IRibbonControl control) {
            var selection = control.Context as Outlook.Selection;
            if (selection == null) return false;

            var attachments = new List<Outlook.Attachment>();
            var mailItems = selection.OfType<Outlook.MailItem>().Where(i => (!Globals.ThisAddIn.Settings.OnlyUnread || i.UnRead)).ToList();

            foreach (var mailItem in mailItems) {
                attachments.AddRange(Utilities.GetMailAttachments(mailItem));
            }

            return mailItems.Count > 0 && attachments.Count > 0;
        }

        /// <summary>
        /// The get tab visibility handler. Only show this tab when the current Context is of Type Explorer
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool GetTabVisibility(Office.IRibbonControl control) {
            return control.Context is Outlook.Explorer;
        }

        /// <summary>
        /// The preflight check method.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private static bool DoPreflightCheck() {
            if (Globals.ThisAddIn.Settings.IsValid) return true;

            MessageBox.Show(
                "The Attachment Handler settings are invalid! Please check your settings! Aborting.",
                "Attachment Handler",
                MessageBoxButton.OK,
                MessageBoxImage.Error);

            return false;
        }

        #region IRibbonExtensibility Members generated code

        public string GetCustomUI(string ribbonID) {
            return GetResourceText("AttachmentHandler.Ribbon.xml");
        }

        #endregion

        #region Ribbon Callbacks generated code
        //Create callback methods here. For more information about adding callback methods, visit http://go.microsoft.com/fwlink/?LinkID=271226

        public void Ribbon_Load(Office.IRibbonUI ribbonUI) { }

        #endregion

        #region Helpers generated code

        private static string GetResourceText(string resourceName) {
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] resourceNames = asm.GetManifestResourceNames();
            for (int i = 0; i < resourceNames.Length; ++i) {
                if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0) {
                    using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i]))) {
                        if (resourceReader != null) {
                            return resourceReader.ReadToEnd();
                        }
                    }
                }
            }
            return null;
        }

        #endregion
    }
}
